#include "ModuleSBThreshold.h"

void ModuleSBThreshold::init(QCVModuleHandlerInterface * parent)
{
	this->parent=parent;
	win=new QWidget();
	layout=new QVBoxLayout(win);

	sb_A=new QDoubleSpinBox(win);
	sb_A->setPrefix(tr("A="));
	sb_B=new QDoubleSpinBox(win);
	sb_B->setPrefix(tr("B="));
	sb_A->setSingleStep(0.005);
	sb_A->setDecimals(4);
	
	l_formula=new QLabel(tr(" Sat = A*(Bri-128)^2+B "),win);
	
	layout->addWidget(l_formula);
	layout->addWidget(sb_A);
	layout->addWidget(sb_B);
	
}
////////////////////////////////////////////////////////////////////////////////
void ModuleSBThreshold::free()
{
	delete win;
}
////////////////////////////////////////////////////////////////////////////////
cv::Mat & ModuleSBThreshold::process()
{
	if(!image.empty())
	{
		if(image.channels()==3 && image.depth()==CV_8U)
		{
			uchar bri=0;
			uchar sat=0;
			
			int nbdata=image.rows*image.cols*3;
			for(int p=0;p<nbdata;p+=3)
			{
				getBriSat(image.data[p],
						  image.data[p+1],
						  image.data[p+2],&bri,&sat);
							   
				if(sat<(uchar)(sb_A->value()*(bri-128)*(bri-128)+sb_B->value()))
				{
					uchar moy=(image.data[p]+image.data[p+1]+image.data[p+2])/3;
					image.data[p]=moy;
					image.data[p+1]=moy;
					image.data[p+2]=moy;
				}
			}
		}
		else
		{
			std::cout<<"Erreur ModuleSBThreshold: image.channels()!=3\n";
		}
	}
	else
	{
		std::cout<<"Erreur ModuleSBThreshold: image.empty()==true\n";
	}
	return image;
}
////////////////////////////////////////////////////////////////////////////////
void ModuleSBThreshold::setInput(int n,const cv::Mat & m)
{
	if(n==0)
	{	
		image=m.clone();
	}
}
////////////////////////////////////////////////////////////////////////////////
QWidget* ModuleSBThreshold::widget()
{
	return win;
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleSBThreshold::getName()
{
	return tr("Seuillage Saturation Brillance");
}
////////////////////////////////////////////////////////////////////////////////
int ModuleSBThreshold::nbInputs()
{
	return 1;
}
////////////////////////////////////////////////////////////////////////////////
bool ModuleSBThreshold::setParams(QString params)
{
	QStringList list_params=params.split(";");
		
	if(list_params.size()==2)
	{
		sb_A->setValue(list_params[0].toFloat());
		sb_B->setValue(list_params[1].toFloat());
		return true;
	}
	else
	{
		return false;
	}	
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleSBThreshold::getParams()
{
	return QString::number(sb_A->value())+tr(";")+
		   QString::number(sb_B->value());
}

////////////////////////////////////////////////////////////////////////////////
QCVModuleInterface * ModuleSBThreshold::clone()
{
	return new ModuleSBThreshold;
}
////////////////////////////////////////////////////////////////////////////////
QString ModuleSBThreshold::help(int id)
{
	if(id==-2)
	{
		return tr("Seuillage celon une parabole Sat Bri");
	}
	else if(id==-1)
	{
		return tr("image");
	}
	else if(id==0)
	{
		return tr("image");
	}
	else
	{
		return tr("erreur");
	}
}
////////////////////////////////////////////////////////////////////////////////
void ModuleSBThreshold::getBriSat(uchar r,uchar g,uchar b,uchar * L,uchar * S)
{
	uchar var_Min = std::min( std::min(r, g), b );    //Min. value of RGB
	uchar var_Max = std::max( std::max(r, g), b );    //Max. value of RGB
	uchar del_Max = var_Max - var_Min; 				//Delta RGB value

	*L = ( var_Max + var_Min ) / 2;

	if ( del_Max == 0 )                     //This is a gray, no chroma...
	{		                                //HSL results from 0 to 1
		*S = 0;
	}
	else                                    //Chromatic data...
	{
		if ( *L < 128 ) *S = (255 * del_Max) / ( var_Max + var_Min );
		else           *S = (255 * del_Max) / ( 512 - var_Max - var_Min );
	}
}
////////////////////////////////////////////////////////////////////////////////
Q_EXPORT_PLUGIN2(ModuleSBThreshold_plugin,ModuleSBThreshold);  
